package main.java.modules.alipay.service.impl;

import java.io.File;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;

import com.alibaba.dubbo.common.utils.StringUtils;
import com.alibaba.dubbo.config.annotation.Service;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.request.AlipayDataDataserviceBillDownloadurlQueryRequest;
import com.alipay.api.request.AlipayTradeCloseRequest;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.alipay.api.response.AlipayDataDataserviceBillDownloadurlQueryResponse;
import com.alipay.api.response.AlipayTradeCloseResponse;
import com.alipay.api.response.AlipayTradePrecreateResponse;
import com.alipay.demo.trade.config.Configs;
import com.alipay.demo.trade.model.ExtendParams;
import com.alipay.demo.trade.model.builder.AlipayTradePrecreateRequestBuilder;
import com.alipay.demo.trade.model.builder.AlipayTradeRefundRequestBuilder;
import com.alipay.demo.trade.model.result.AlipayF2FPrecreateResult;
import com.alipay.demo.trade.model.result.AlipayF2FRefundResult;
import com.alipay.demo.trade.utils.ZxingUtils;

import main.java.common.constants.Constants;
import main.java.common.model.Product;
import main.java.common.util.CommonUtil;
import main.java.modules.alipay.service.AlipayService;
import main.java.modules.alipay.util.AlipayConfig;
import net.sf.json.JSONObject;

@Service
public class AlipayServiceImpl implements AlipayService {
	private static final Logger logger = LoggerFactory.getLogger(AlipayServiceImpl.class);
	
	//回调参数notify_url
	@Value("${alipay.notify.url}")
	private String notify_url;
	
	@Override
	public String aliPay(Product product) {
		// TODO Auto-generated method stub
		logger.info("订单号：{} 生成支付宝支付码", product.getOutTradeNo());
		String message = Constants.SUCCESS;
		//二维码路径
		String imgPath = Constants.QRCODE_PATH + Constants.SF_FILE_SEPARATOR + 
				product.getOutTradeNo() + ".png";
		String outTradeNo = product.getOutTradeNo();
		String subject = product.getSubject();
		String totalAmount = CommonUtil.divide(product.getTotalFee(), "100").toString();
		//若该字段为"",则默认为appid对应的PId
		String sellerId = "";
		//商户门店编号，通过门店号和商家后台可以配置精准到门店的折扣信息
		String storeId = "test_store_id";
		//业务扩展参数，可添加由支付宝分配的系统商编号
		ExtendParams extendParams = new ExtendParams();
		extendParams.setSysServiceProviderId("2088100200300400500");
		//订单详细描述
		String body = product.getBody();
		//支付超时
		String timeoutExpress = "120m";
		//创建扫码支付请求builder
		AlipayTradePrecreateRequestBuilder builder = new AlipayTradePrecreateRequestBuilder()
				.setSubject(subject)
				.setTotalAmount(totalAmount)
				.setOutTradeNo(outTradeNo)
				.setSellerId(sellerId)
				.setBody(body)
				.setStoreId(storeId)
				.setTimeoutExpress(timeoutExpress)
				.setNotifyUrl(notify_url)
				.setExtendParams(extendParams);
		
		AlipayF2FPrecreateResult result = AlipayConfig.getAlipayTradeService().tradePrecreate(builder);
		switch(result.getTradeStatus()) {
		case SUCCESS:
			logger.info("支付宝预下单成功");
			AlipayTradePrecreateResponse response = result.getResponse();
			dumpResponse(response);
			ZxingUtils.getQRCodeImge(response.getQrCode(), 256, imgPath);
			break;
		
		case FAILED:
			logger.info("支付宝预下单失败");
			message = Constants.FAIL;
			break;
			
		case UNKNOWN:
			logger.info("预下单状态未知");
			message = Constants.FAIL;
			break;
			
		default :
			logger.info("交易返回异常");
			message = Constants.FAIL;
			break;
		}
		
		return message;
	}
	/**
	 * 日志打印应答
	 * @param response
	 */
	private void dumpResponse(AlipayTradePrecreateResponse response) {
		// TODO Auto-generated method stub
		if(response != null) {
			logger.info("code:{}, msg:{}", response.getCode(), response.getMsg());
			if(StringUtils.isNotEmpty(response.getSubCode())) {
				logger.info("subCode:{}, subMsg:{}", response.getSubCode(), response.getSubMsg());
			}
			logger.info("body:{}", response.getBody());
		}
	}

	@Override
	public String aliRefund(Product product) {
		// TODO Auto-generated method stub
		logger.info("订单号：{}支付宝退款",product.getOutTradeNo());
		String message = Constants.SUCCESS;
		//外部订单号，需要退款交易的商户外部订单号
		String outTradeNo = product.getOutTradeNo();
		//退款金额，必须小于等于订单的支付金额
		String refundAmount = CommonUtil.divide(product.getTotalFee(), "100").toString();
		String refundReason = "退款原因。。。";
		
		String storeId = "test_store_id";
		
		AlipayTradeRefundRequestBuilder builder = new AlipayTradeRefundRequestBuilder()
				.setOutTradeNo(outTradeNo)
				.setRefundAmount(refundAmount)
				.setRefundReason(refundReason)
				.setStoreId(storeId);
		
		AlipayF2FRefundResult result = AlipayConfig.getAlipayTradeService().tradeRefund(builder);
		switch (result.getTradeStatus()) {
			case SUCCESS:
				logger.info("支付宝退款成功");
				break;
			
			case FAILED:
				logger.info("支付宝退款失败");
				message = Constants.FAIL;
				break;
			
			case UNKNOWN:
				logger.info("退款状态未知");
				message = Constants.FAIL;
				break;
				
			default :
				logger.info("交易返回异常");
				message = Constants.FAIL;
				break;
		}
		
		return message;
	}

	@Override
	public String aliCloseOder(Product product) {
		// TODO Auto-generated method stub
		logger.info("订单号：{}交易关闭", product.getOutTradeNo());
		String message = Constants.SUCCESS;
		try {
			String imgPath = Constants.QRCODE_PATH + Constants.SF_FILE_SEPARATOR 
					+ product.getOutTradeNo() + "png";
			File file = new File(imgPath);
			if(file.exists()) {
				AlipayClient alipayClient = AlipayConfig.getAlipayClient();
				AlipayTradeCloseRequest alipayCloseRequest = new AlipayTradeCloseRequest();
				alipayCloseRequest.setBizContent("{" + " \"out_trade_no\"" + product.getOutTradeNo() + "\"" 
						+ "}");
				AlipayTradeCloseResponse response = alipayClient.execute(alipayCloseRequest);
				//扫码未支付
				if(response.isSuccess()) {
					logger.info("订单号:{}交易关闭成功并删除二维码", product.getOutTradeNo());
					file.delete();
				} else if("ACQ.TRADE_NOT_EXIST".equals(response.getSubCode())) {
					logger.info("订单号：{} {} 预下单未扫码交易关闭", product.getOutTradeNo(), response.getSubMsg());
				} else if("ACQ.TRADE_STATUS_ERROR".equals(response.getSubCode())) {
					logger.info("订单号：{} {}", product.getOutTradeNo(), response.getSubMsg());
				} else {
					logger.info("订单号："+ product.getOutTradeNo() + " 交易关闭失败 {} {}",  response.getSubCode(),response.getSubMsg());
					message = Constants.FAIL;			
				}
			}
		} catch(Exception e) {
			e.printStackTrace();
			message = Constants.FAIL;
			logger.info("订单号：{} 交易关闭异常",product.getOutTradeNo() );
		}
		return message;
	}

	@Override
	public String downloadBillUrl(String billDate, String billType) {
		// TODO Auto-generated method stub
		logger.info("获取订单下载地址：{}",billDate);
		String downloadBillUrl = "";
		try {
			AlipayDataDataserviceBillDownloadurlQueryRequest request = new AlipayDataDataserviceBillDownloadurlQueryRequest();
			request.setBizContent("{" + " \"bill_type\":\"trade\"," 
			+ " \"bill_data\":\"2018-3-10\"" + " }");
			AlipayDataDataserviceBillDownloadurlQueryResponse response = AlipayConfig.getAlipayClient().execute(request);
			if(response.isSuccess()) {
				logger.info("获取订单地址成功：{}", billDate);
				downloadBillUrl = response.getBillDownloadUrl();
			} else {
				logger.info("获取订单地址失败：{} {}",response.getSubMsg(), billDate);
			}
		} catch(Exception e) {
			e.printStackTrace();
			logger.info("获取订单地址异常：{}", billDate);
		}
		return downloadBillUrl;
	}

	@Override
	public String aliPayPc(Product product) {
		// TODO Auto-generated method stub
		logger.info("支付宝pc支付下单:{}", product.getOutTradeNo());
		AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();
		//前端回调地址
		String returnUrl = "";
		request.setReturnUrl(returnUrl);
		request.setNotifyUrl(notify_url);
		JSONObject bizContent = new JSONObject();
		bizContent.put("out_trade_no", product.getOutTradeNo());
		bizContent.put("total_amount", product.getTotalFee());
		//订单标题
		bizContent.put("subject", product.getSubject());
		//收款账号
		bizContent.put("seller_id", Configs.getPid());
		//电脑网站支付
		bizContent.put("product_code", "FAST_INSTANT_TRADE_PAY");
		bizContent.put("body", "");
		String biz = bizContent.toString().replaceAll("\"", "'");
		request.setBizContent(biz);
		logger.info("业务参数：" + request.getBizContent());
		String form = Constants.FAIL;
		try {
			form = AlipayConfig.getAlipayClient().pageExecute(request).getBody();
		} catch(AlipayApiException e) {
			logger.error("支付宝构造表单失败：", e);
		}
		return form;
	}

}
